#! /usr/bin/perl 

# huanlf@gmail.com
# date: 2009-08-02
# download ipa from weiphone.com 

use strict;
use warnings;
use utf8;
use Encode;
#use POSIX qw(strftime);

use threads;
use WWW::Mechanize;
use Thread::Semaphore;
use threads::shared;
use Thread::Queue;
my $q = Thread::Queue->new();    # A new empty queue

$| = 1;
my $dir = $ENV{HOME} . "/hh/tmp/ipa";

## download from here, for example, "http://bbs.weiphone.com/read.php?tid=408888"
my $url = shift or die "no url given\n";

## files match the regexp will be downloaded, rar and ipa for default
my $regexp = shift || '\.(ipa|rar)';

my $mech  = WWW::Mechanize->new(quiet => 1, onerror => undef, timeout => 60);
#$mech->agent_alias('Windows IE 6');
$mech->agent_alias('Linux Mozilla');
$mech->stack_depth(2);
$mech->get($url);

my $threads_max = 5;
my $mutux = Thread::Semaphore->new( $threads_max );

my @links = $mech->find_all_links( text_regex => qr/$regexp$/oi );
my %files_download :shared;

my $i = 1;

## clean files that downloading and downloaded
$SIG{INT} = $SIG{HUP} = $SIG{TERM} = $SIG{QUIT} = \&clean_files;

for (@links) {
    #print $i++, "\t", $_->text(), "\t", $_->url(), "\n";
    print $i++, "\t", $_->text(), "\n";
    $mutux->down;
    $q->enqueue( 1 );
    threads->create( "download", $_)->detach;
}

while ( my $left = $q->pending ) {
    print "$left . ";
    sleep 1;
}
print "\n";

sub download()
{
    my $link = shift;
    my $file = $link->text();

    ## my $file = encode('utf-8', decode( 'gbk', $link->text() ) );
    ## print "[", $link->text(), "] [", $link->url(), "]\n";

    ## downloaded before
    if ( -e "$dir/$file" ) {
        $mutux->up;
        $q->dequeue();
        return 0;
    }

    #$mech->follow_link( text_regex => qr/download/i );
    $files_download{ "$dir/$file" } = 0;    ## not down
    $mech->get($link->url(), ':content_file' => "$dir/$file" );

    if ( $mech->success ) {
        #print "DONE: $dir/$file\n";
        $files_download{ "$dir/$file" } = 1;    ## done
    }
    else {
        warn "FAIL: $dir/$file\n";
        unlink "$dir/$file";
        delete $files_download{ "$dir/$file" };
    }

    ## told the main thread we done
    $q->dequeue();

    ## be polite
    sleep 1;

    ## release resource
    $mutux->up;
}

## delete the files not done
sub clean_files()
{
    for ( keys %files_download ) {
        if ( $files_download{$_} == 0 ) {  
            print "deleting $_ ...\n";
            unlink if -e;
        }
    }
    exit 1;
}
